package com.jzr.medical.auth;

import com.jzr.medical.db1.service.UserService;
import com.jzr.medical.util.SpringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * Created by Shuangyao
 * 22:55 2018/10/15
 */
public class JwtAuthenticationFilter extends OncePerRequestFilter {

    private Logger logger = LoggerFactory.getLogger(JwtAuthenticationFilter.class);

    @Autowired
    private UserService userService;

    public JwtAuthenticationFilter(){
        userService = SpringUtil.getBean(UserService.class);
    }

    //1.从每个请求header获取token
    //2.调用前面写的validateToken方法对token进行合法性验证
    //3.解析得到username，并从database取出用户相关信息权限
    //4.把用户信息以UserDetail形式放进SecurityContext以备整个请求过程使用。
    // （例如哪里需要判断用户权限是否足够时可以直接从SecurityContext取出去check
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        int code = HttpServletResponse.SC_FORBIDDEN;
        String msg = "无权访问";
        try {
            HttpSession session = request.getSession(false);
            if (session != null) {
                UserDetails userDetails = (UserDetails) session.getAttribute("userDetails");
                //System.out.println(userDetails);
                if (userDetails != null) {
                    Authentication authentication = new UsernamePasswordAuthenticationToken(
                            userDetails, null, userDetails.getAuthorities());
                    SecurityContextHolder.getContext().setAuthentication(authentication);

                } else {
                    if(logger.isInfoEnabled()) {
                        logger.info(request.getParameter("username") + " :Session timeout");
                    }
                }
            }
            super.doFilter(request, response, filterChain);

        }catch (Exception e){
            e.printStackTrace();
            code = HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
            msg = "系统错误，请联系技术";
            writeResult(request,response,code,msg);
            return;
        }
    }

    /**
     * Get Bear jwt from request header Authorization.
     *
     * @param request servlet request.
     * @return token or null.
     */
    private String getJwtFromRequest(HttpServletRequest request) {
        String token = request.getHeader("Authorization");
        if(token == null) {
            token = request.getHeader("authorization");
        }
        if (token != null && token.startsWith("Bearer")) {
            return token.replace("Bearer ", "");
        }
        return null;
    }

    private void writeResult(HttpServletRequest request, HttpServletResponse response,int code, String msg) throws IOException {
        SecurityContextHolder.getContext().setAuthentication(null);
        request.setAttribute("vStatus",code);
        request.setAttribute("vMessage",msg);
        response.setStatus(code);
        response.setContentType("application/json;charset=utf-8");
        PrintWriter out = response.getWriter();
        out.write("{\"code\":" + code + ",\"status\":" + code + ",\"msg\":\"" + msg + "\"" + ",\"message\":\"" + msg + "\"}");
        out.flush();
        out.close();
    }

}
